package com.hksj.Intelligentmanagement.auth.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hksj.Intelligentmanagement.auth.dto.RoleDTO;
import com.hksj.Intelligentmanagement.auth.dto.RoleMenuDTO;
import com.hksj.Intelligentmanagement.auth.dto.UserRoleDTO;
import com.hksj.Intelligentmanagement.auth.entity.Role;
import com.hksj.Intelligentmanagement.auth.entity.RoleMenu;
import com.hksj.Intelligentmanagement.auth.entity.UserRole;
import com.hksj.Intelligentmanagement.auth.mapper.RoleMapper;
import com.hksj.Intelligentmanagement.auth.vo.MenuVo;
import com.hksj.Intelligentmanagement.auth.vo.RoleVo;
import com.hksj.Intelligentmanagement.auth.vo.UserRoleMenuVo;
import com.hksj.Intelligentmanagement.common.Rest;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 角色表 服务类
 * @author chenxingqing
 */
@Service
public class RoleService extends ServiceImpl<RoleMapper, Role> {

    @Autowired
    private RoleMenuService roleMenuService;

    @Autowired
    private UserRoleService userRoleService;

    @Autowired
    private MenuService menuService;

    @Transactional
    public Rest createRole(RoleDTO roleDTO) {
        //保存角色
        Role role = new Role();
        BeanUtils.copyProperties(roleDTO,role);
        role.setId(null);
        baseMapper.insert(role);

        //保存校色权限关联关系
        saveRoleMenu(roleDTO);
        return Rest.ok();
    }

    @Transactional
    public Rest updateRole(RoleDTO roleDTO) {
        //保存角色
        Role role = new Role();
        BeanUtils.copyProperties(roleDTO,role);
        baseMapper.updateById(role);

        //删除之前的角色权限关联关系
        deleteRoleMenu(roleDTO.getId());

        //保存角色权限关联关系
        saveRoleMenu(roleDTO);
        return Rest.ok();
    }

    public Rest deleteRole(String roleId) {
        LambdaQueryWrapper<UserRole> userRoleQuery = new QueryWrapper<UserRole>().lambda()
                .eq(UserRole::getRoleId, roleId);
        int count = userRoleService.count(userRoleQuery);
        if (count > 0){
            return Rest.fail("角色已分配给用户，请解除分配后再操作删除");
        }
        //删除角色信息
        baseMapper.deleteById(roleId);

        //删除角色关联关系
        deleteRoleMenu(roleId);

        return Rest.ok();
    }

    public Rest<RoleVo> getRole(String roleId) {
        //获取角色信息
        Role role = baseMapper.selectById(roleId);
        RoleVo roleVo = new RoleVo();
        BeanUtils.copyProperties(role,roleVo);

        //获取角色关联的权限
        List<MenuVo> menuVos = baseMapper.listRoleMenu(roleId);

        //获取树型结构
        List<MenuVo> menuTreeInAll = menuService.getMenuTreeInAll(menuVos);
        roleVo.setMenus(menuTreeInAll);

        return Rest.ok(roleVo);
    }

    /**
     * 保存角色权限关联关系
     * @param roleDTO
     */
    private void saveRoleMenu(RoleDTO roleDTO){
        //保存角色权限关联关系
        if(!ObjectUtils.isEmpty(roleDTO.getRoleMenus())){
            List<RoleMenu> roleMenus = new ArrayList<>();
            RoleMenu tRoleMenu = null;
            for (RoleMenuDTO roleMenuDTO : roleDTO.getRoleMenus()) {
                tRoleMenu = new RoleMenu();
                BeanUtils.copyProperties(roleMenuDTO,tRoleMenu);
                roleMenus.add(tRoleMenu);
            }
            roleMenuService.saveBatch(roleMenus);
        }
    }

    /**
     * 删除角色关联关系
     * @param roleId
     */
    private void deleteRoleMenu(String roleId){
        LambdaQueryWrapper<RoleMenu> query = new QueryWrapper<RoleMenu>().lambda()
                .eq(RoleMenu::getRoleId, roleId);
        roleMenuService.remove(query);
    }

    /**
     * 查询所有角色
     * @param name
     * @param roleKey
     * @param status
     * @return
     */
    public Rest<List<RoleVo>> listRole(String name, String roleKey, String status) {
        List<RoleVo> roles = baseMapper.listRole(name,roleKey,status);
        return Rest.ok(roles);
    }

    /**
     * 查询分配给用户的角色
     * @param userId
     * @return
     */
    public Rest<UserRoleMenuVo> listUserRoleWithMenus(String userId) {
        List<RoleVo> roles = listUserRole(userId);
        List<MenuVo> menuVos = menuService.getUserMenuTreeInAll(userId);
        UserRoleMenuVo userRoleVo = new UserRoleMenuVo();
        userRoleVo.setRoles(roles);
        userRoleVo.setMenus(menuVos);
        return Rest.ok(userRoleVo);
    }

    public List<RoleVo> listUserRole(String userId){
        return baseMapper.listUserRole(userId);
    }

    public List<String> listUserRoleKey(String userId){
        List<RoleVo> roles = listUserRole(userId);
        List<String> roleKeyList = roles.stream().map(roleVo -> roleVo.getRoleKey()).collect(Collectors.toList());
        return roleKeyList;
    }


    /**
     * 分配用户角色
     * @param userRoleDTO
     * @return
     */
    public Rest assignRole(UserRoleDTO userRoleDTO) {
        //删除之前的用户角色关联关系
        LambdaQueryWrapper<UserRole> query = new QueryWrapper<UserRole>().lambda()
                .eq(UserRole::getUserId, userRoleDTO.getUserId());
        userRoleService.remove(query);

        //添加新的用户角色关联关系
        if (!ObjectUtils.isEmpty(userRoleDTO) && !ObjectUtils.isEmpty(userRoleDTO.getRoleIds())){
            List<UserRole> userRoles = new ArrayList<>();
            UserRole tUserRole = null;
            for (String roleId : userRoleDTO.getRoleIds()) {
                tUserRole = new UserRole();
                tUserRole.setUserId(userRoleDTO.getUserId());
                tUserRole.setRoleId(roleId);
                userRoles.add(tUserRole);
            }
            userRoleService.saveBatch(userRoles);
        }
        return Rest.ok();
    }
}
